﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PaintRuler
{
    public class PUBLIC_WAY
    {
        /// <summary>  
        /// 由结构体转换为byte数组  
        /// </summary>  
        public static byte[] GStructureToByte<T>(T structure)
        {
            int size = Marshal.SizeOf(typeof(T));
            byte[] buffer = new byte[size];
            IntPtr bufferIntPtr = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structure, bufferIntPtr, true);
                Marshal.Copy(bufferIntPtr, buffer, 0, size);
            }
            finally
            {
                Marshal.FreeHGlobal(bufferIntPtr);
            }
            return buffer;
        }


        /// <summary>  
        /// 由byte数组转换为结构体  
        /// </summary>  
        public static T GByteToStructure<T>(byte[] dataBuffer)
        {
            object structure = null;
            int size = Marshal.SizeOf(typeof(T));
            IntPtr allocIntPtr = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.Copy(dataBuffer, 0, allocIntPtr, size);
                structure = Marshal.PtrToStructure(allocIntPtr, typeof(T));
            }
            finally
            {
                Marshal.FreeHGlobal(allocIntPtr);
            }
            return (T)structure;
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct BITMAPFILEHEADER
    {
        public ushort bfType;                  // 位图文件的类型，必须为BMP (2个字节)
        public uint bfSize;                  // 位图文件的大小，以字节为单位 (4个字节)
        public ushort bfReserved1;             // 位图文件保留字，必须为0 (2个字节)
        public ushort bfReserved2;             // 位图文件保留字，必须为0 (2个字节)
        public uint bfOffBits;               // 位图数据的起始位置，以相对于位图 (4个字节)
    }


    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct BITMAPINFOHEADER
    {
        public uint biSize;           // 本结构所占用字节数  (4个字节)
        public int biWidth;           // 位图的宽度，以像素为单位(4个字节)
        public int biHeight;          // 位图的高度，以像素为单位(4个字节)
        public ushort biPlanes;          // 目标设备的级别，必须为1(2个字节)
        public ushort biBitCount;        // 每个像素所需的位数，必须是1(双色)、// 4(16色)、8(256色)、
                                         //24(真彩色)或32(增强真彩色)之一 (2个字节)
        public uint biCompression;    // 位图压缩类型，必须是 0(不压缩)、 1(BI_RLE8 
                                      // 压缩类型)或2(BI_RLE4压缩类型)之一 ) (4个字节)
        public uint biSizeImage;      // 位图的大小，以字节为单位(4个字节)
        public int biXPelsPerMeter;   // 位图水平分辨率，每米像素数(4个字节)
        public int biYPelsPerMeter;   // 位图垂直分辨率，每米像素数(4个字节)
        public uint biClrUsed;        // 位图实际使用的颜色表中的颜色数(4个字节)
        public uint biClrImportant;   // 位图显示过程中重要的颜色数(4个字节)
    }


    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct RGBQUAD
    {
        public byte rgbBlue;          // 蓝色的亮度(值范围为0-255)
        public byte rgbGreen;         // 绿色的亮度(值范围为0-255)
        public byte rgbRed;           // 红色的亮度(值范围为0-255)
        public byte rgbReserved;      // 保留，必须为0
    }


    public partial class FormOpenBMP : Form
    {
        public FormOpenBMP()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string _bmp_file_path = "";
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                // 设置文件过滤器（可选）
                openFileDialog.Filter = "BMP文件 (*.bmp)|*.bmp"; // 可以根据需要修改过滤器
                // 若文件夹消失了，则打开系统默认地址
                openFileDialog.Title = "选择bmp文件";
                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 获取选择的文件路径
                    _bmp_file_path = openFileDialog.FileName;
                }
                else
                {
                    return;
                }
            }

            using (FileStream fileStream = new FileStream(_bmp_file_path, FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[14]; // 用于存储读取的数据的缓冲区
                fileStream.Read(buffer, 0, 14);

                BITMAPFILEHEADER _file_header = PUBLIC_WAY.GByteToStructure<BITMAPFILEHEADER>(buffer);

                buffer = new byte[40]; // 用于存储读取的数据的缓冲区
                fileStream.Read(buffer, 0, 40);

                BITMAPINFOHEADER _info_header = PUBLIC_WAY.GByteToStructure<BITMAPINFOHEADER>(buffer);
            }
        }
    }
}
